package tuling.netty.splitpacket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import tuling.netty.splitpacket.encoding.RgsCustomizeDecode;
import tuling.netty.splitpacket.encoding.RgsCustomizeEncode;

/**
 * @author RenGaoshuai
 * @date 2023/11/30 9:39
 * @description
 */
public class SplitPacketServer {

    public static void main(String[] args) {
        //可以把这个对象看成线程池，内部绑定了selector对象
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workGroup = new NioEventLoopGroup(1);

        try {

            //服务端启动对象
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap
                    //设置两个线程组
                    .group(bossGroup, workGroup)
                    //使用netty提供的通道
                    .channel(NioServerSocketChannel.class)
                    //初始化服务器连接队列大小（如果有10w个连接，短时间处理不完就放到此队列中）
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    //创建通道对象
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //对workGroup的socketChannel设置处理器（我们的业务代码均在此处理器中完成）
                            ChannelPipeline pipeline = socketChannel.pipeline();
//                            //自定义分隔符
//                            pipeline.addLast("delimit", new DelimiterBasedFrameDecoder(1024, Unpooled.copiedBuffer("_".getBytes())));
//                            //向pipeline加入编解码器
//                            pipeline.addLast("decoder", new StringDecoder());
//                            pipeline.addLast("encoder", new StringEncoder());
                            //自定义粘包处理
                            pipeline.addLast("rgsCustomizeEncoder", new RgsCustomizeEncode());
                            pipeline.addLast("rgsCustomizeDecoder", new RgsCustomizeDecode());
                            pipeline.addLast(new SplitPacketServerHandler());
                        }
                    });

            System.out.println("server start success");

            //绑定服务端启动端口9000，sync()表示代码同步执行，绑定端口成功后，才能往下执行后续代码。
            //如果不加sync()，那么绑定9000端口是异步操作，快速执行后续代码的话会出现问题。当然你可以设置监听器去解决
            ChannelFuture cf = bootstrap.bind(9000).sync();

            //对通道关闭监听，这里的sync()方法作用同上
            cf.channel().closeFuture().sync();


        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("server interrupted exception");
        } finally {

            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }
}
